package shared.file

import java.io._

import shared.query._

object SharedFolder {
  import scala.xml._
  def collectAllFiles(root: File) = {
    def collect(r: File, l: List[File]):List[File] = {
      if(l.find( _ == r).isDefined) {
        l
      } else if(r.isFile) {
        r :: l
      } else {
        r.listFiles.toList.foldRight(l) {collect(_, _)}
      }
    }
    collect(root, Nil)
  }
  
   object LocalFileReference {
    def fromXML(node: scala.xml.Node) = {
      val file = new File( (node \ "path").text)
      val root = new File( (node \ "parent").text)
      val ref = new LocalFileReference(file, root)
      ref.description = (node \ "description").text
      ref.keywords = (node \ "kw").text
      ref
    }
  }
  
  
  def fromXML(n: Node) = {
    val root = new File( (n \ "root").text)
    val shared = (n \ "shared").text.toBoolean
    val files = (n \ "localFile").map{ LocalFileReference.fromXML( _ )}.toList
    new SharedFolder(root, shared, files)
  }
  
}

class SharedFolder(val root: File, var shared: Boolean, val allFiles: List[LocalFileReference]) {
  def this(f: File, b: Boolean) = this(f, b, SharedFolder.collectAllFiles(f).map{ new LocalFileReference(_, f)})
  def this(f: File) = this(f, true)
  
  if(!root.isDirectory) {
    error("file: " + root + " is not a folder")
  }
  
  def refresh = {
    val other = new SharedFolder(root, shared)
    allFiles.foreach { f =>
      val of = other.getFile(f.path)
      of.map { i =>  i.keywords = f.keywords; i.description = f.description}
    }
    other
  }
  
  def findFiles(query: Query) = if(!shared) Nil else for(file <- allFiles; if(query.matches(file))) yield file.toRemote
  
  def openFile(ref: LocalFileReference) = ref.open
  
  def getFile(path: String) = allFiles.find( _.path == path )
  
  def toXML = {
    import scala.xml._
    val nodeSeq = NodeSeq.fromSeq(allFiles.map{_.toXML})
    <folder><root>{root.getAbsolutePath}</root><shared>{shared}</shared>{nodeSeq}</folder>
  }
  
  override def hashCode = root.hashCode + {if(shared) 1 else 0}
  override def equals(o: Any) = {
    o match {
      case f: SharedFolder => this.root.getAbsoluteFile == f.root.getAbsoluteFile && this.shared == f.shared && this.allFiles == f.allFiles
      case _ => false
    }
  }
}
